#!/usr/bin/env python
#coding:utf8

import sys
import time
import random
from datetime import datetime, timedelta, date

import requests
from bs4 import BeautifulSoup
import openpyxl

# 延时1-5秒，防止被检测到
def sleep():
    time.sleep(random.randrange(1,5))

# 考勤系统数据读取
class Crawler():
    def __init__(self):
        self.base_url = 'http://kqgl.jh:8008'
        self.get_login_url = '%s/signInfo/faces/login.jsp' % self.base_url
        self.logout_url = '%s/signInfo/faces/top.jsp' % self.base_url
        self.person_do_check1_url = '%s/signInfo/faces/check/person_do_check1.jsp' % self.base_url
        self.center_url = '%s/signInfo/faces/center.jsp' % self.base_url
        self.is_login = True
        self.cardid = ''

    def login(self, user_name, password='password'):
        self.headers = {
            'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
            'Accept-Encoding':'gzip,deflate',
            'Accept-Language':'zh-CN,zh;q=0.9,en;q=0.8',
            'Cache-Control':'max-age=0',
            'Connection':'keep-alive',
            # 'Cookie': '%s=%s' % (cookies.keys()[0], cookies.values()[0]),
            'Content-Type':'application/x-www-form-urlencoded',
            'Host':'kqgl.jh:8008',
            'Upgrade-Insecure-Requests':'1',
            'User-Agent':'Mozilla/5.0(WindowsNT 6.1;Win64;x64) AppleWebKit/537.36(KHTML,likeGecko) Chrome/68.0.3440.106 Safari/537.36'
        }

        r = requests.get(self.get_login_url, headers=self.headers, timeout=10)
        if r.status_code != 200:
            self.is_login = False
            msg = '页面访问出错:%s %d' % (self.get_login_url, r.status_code)
            raise Exception(msg)

        self.cookies = r.cookies

        soup = BeautifulSoup(r.content, "html.parser")
        soup_form = soup.find(id='loginform')
        # print(soup_form.attrs)
        self.post_login_url = '%s/%s' % (self.base_url, soup_form.attrs['action'])
        # print(self.post_login_url)

        sleep()

        soup_viewState = soup_form.find(id='javax.faces.ViewState')
        # print(soup_viewState.attrs)
        self.viewStatute = soup_viewState.attrs['value']

        self.headers['Origin'] = self.base_url
        self.headers['Referer'] = self.get_login_url

        form_data = {
            'loginform:staffId': user_name,
            'loginform:password': password,
            'loginform_SUBMIT': '1',
            'loginform:_link_hidden_': '',
            'loginform:_idcl': 'loginform:loginBtn',
            'javax.faces.ViewState': self.viewStatute
        }

        r = requests.post(self.post_login_url, data=form_data, headers=self.headers, cookies=self.cookies, timeout=10)
        if r.status_code != 200:
            self.is_login = False
            msg = '页面访问出错:%s %d' % (self.get_login_url, r.status_code)
            raise Exception(msg)
        # print(r.text)
        self.cookies = r.cookies

    # 查询考勤记录
    def query_person_do_check1(self, start_date, end_date):
        self.headers['Referer'] = self.center_url
        r = requests.get(self.person_do_check1_url, headers=self.headers, cookies=self.cookies, timeout=10)
        if r.status_code != 200:
            self.is_login = False
            msg = '页面访问出错:%s %d' % (self.person_do_check1_url, r.status_code)
            raise Exception(msg)

        # print(r.text)
        # 获取身份证
        soup = BeautifulSoup(r.content, "html.parser")
        # print(soup.find(id='form1'))
        soup_form_cardid = soup.find(id='form1:_idJsp9')

        try:
            self.cardid = soup_form_cardid.attrs['value']
            # print(self.cardid)
            soup_viewState = soup.find(id='javax.faces.ViewState')
            self.viewStatute = soup_viewState.attrs['value']

            sleep()

            self.headers['Referer'] = self.person_do_check1_url

            form_data = {
                'form1:_idJsp0': '',
                'form1:_idJsp1': start_date,
                'form1:endDate': end_date,
                'form1:_idJsp2': '0',
                'form1:select_proj': 'all',
                'form1:_idJsp8': '查  询',
                'form1:_idJsp9': self.cardid,
                'form1:_idJsp66': '1',
                'form1_SUBMIT': '1',
                'form1:_link_hidden_': '',
                'form1:_idcl': '',
                'javax.faces.ViewState': self.viewStatute
            }

            r = requests.post(self.person_do_check1_url, data=form_data, headers=self.headers, cookies=self.cookies,
                              timeout=10)
            if r.status_code != 200:
                self.is_login = False
                msg = '页面访问出错:%s %d' % (self.get_login_url, r.status_code)
                raise Exception(msg)

            # r.encoding = 'utf-8'
            soup = BeautifulSoup(r.content, "html.parser")
            # print(soup.find(id='form1'))
            soup_table = soup.find(id='form1:_idJsp10:tbody_element')
            # print(soup_table)
            # print(soup_table.attrs)
            # print(soup_table.tr)

            # 解析报文，返回多日考勤记录
            out_do_check_list = []
            soup_tr_list = soup_table.find_all('tr')
            # print(soup_tr_list)
            for soup_tr in soup_tr_list:
                # 一天考勤记录
                one_day_do_check = []
                out_do_check_list.append(one_day_do_check)
                tmp_list = []

                soup_td_list = soup_tr.find_all('td')
                # print(soup_td_list)
                i = 0
                for soup_td in soup_td_list:
                    value = soup_td.get_text().encode('gbk', 'ignore')
                    tmp_list.append(value)
                    if i in (1, 2, 6):
                        one_day_do_check.append(value)
                    i += 1

            return out_do_check_list
        except:
            self.is_login = False

def main(star, end):
    txt_file_name = datetime.today().strftime("%Y-%m-%d") + '.txt'
    f = open(txt_file_name, 'a')
    wb = openpyxl.load_workbook('项目人员分组.xlsx')
    ws = wb.active
    res = ws['D']
    for names in res:
        name = names.value
        if name == 'attendance_group' or name is None:
            continue
        crawler = Crawler()
        crawler.login(name)
        if crawler.is_login:
            sleep()
            results = crawler.query_person_do_check1(star, end)
            if crawler.is_login:
                # print('登录成功')
                if results is None or len(results) == 0:
                    # print(name + '周末未加班')
                    continue
                # print('开始记录考勤记录')
                for result in results:
                    f.write(name)
                    f.write(',')
                    attendance_date = str(result[0], encoding='utf-8') + ' 00:00:00'
                    f.write(attendance_date)
                    f.write(',')
                    in_date = str(result[0], encoding='utf-8') + ' ' + str(result[1], encoding='utf-8')
                    f.write(in_date)
                    f.write(',')
                    back_date = str(result[0], encoding='utf-8') + ' ' + str(result[2], encoding='utf-8')
                    f.write(back_date)
                    f.write('\n')
            else:
                print(name)
                print('用户名密码错误')
                continue
        else:
            print(name)
            print('用户名密码错误')
            continue

def judge_date(star):
    star = datetime.strptime(star, "%Y-%m-%d")
    week_day = star.weekday()
    if week_day == 0:
        star_time = star - timedelta(days=2)
        end_time = star - timedelta(days=1)
    elif week_day == 1:
        star_time = star - timedelta(days=2)
        end_time = star - timedelta(days=3)
    elif week_day == 2:
        star_time = star - timedelta(days=3)
        end_time = star - timedelta(days=4)
    elif week_day == 3:
        star_time = star - timedelta(days=4)
        end_time = star - timedelta(days=5)
    elif week_day == 4:
        star_time = star - timedelta(days=5)
        end_time = star - timedelta(days=6)
    elif week_day == 5:
        star_time = star - timedelta(days=6)
        end_time = star - timedelta(days=7)
    else:
        star_time = star - timedelta(days=7)
        end_time = star - timedelta(days=8)
    return end_time.strftime("%Y-%m-%d"), star_time.strftime("%Y-%m-%d")


if __name__ == "__main__":
    if len(sys.argv) == 1:
        input_date = datetime.today().strftime("%Y-%m-%d")
    else:
        input_date = sys.argv[1]
    # 判断日期关系
    star_date, end_date = judge_date(input_date)
    main(star_date, end_date)
